using System;
using System.Collections.Generic;
using DC2010.Objects.Base;
using DC2010.Objects.Common;
using System.Xml.Serialization;

namespace DC2010.Objects
{
    [Serializable]
    public class CreatureInfo : BaseInfo
    {
        public Attributes Attributes { get; set; }

        /// <summary>
        /// 0-male, 1-female
        /// </summary>
        [XmlAttribute]
        public int Sex { get; set; }

        /// <summary>
        /// Race ID
        /// </summary>
        [XmlAttribute]
        public string RaceId { get; set; }

        /// <summary>
        /// Items in inventory. Predefined items
        /// </summary>
        public Inventory Inventory { get; set; }

        /// <summary>
        /// Some game mechanics can react to monsters only. We have to know what type on creature is this.
        /// </summary>
        [XmlAttribute]
        public CreatureType CreatureType { get; set; }
		
        public CreatureAbilites Abilities { get; set; }
		
        public CreatureFlags Flags { get; set; }
		
        public CreatureOuches Ouches { get; set; }
		
		public CreatureAIFlags AIFlags { get; set; }
		
		public Resistances Resistances { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public Directions Facing { get; set; }

        /// <summary>
        /// Defines the size of the creature on the floor. 
        /// Value 0 means there can be 4 creatures per tile (like Screamers), 
        /// Value 1 means there can be 2 creatures per tile (like Worms) and 
        /// Value 2 means there can be only one creature per tile (like Dragon). 
        /// Value 3 is not used.
        /// </summary>
        [XmlAttribute]
        public int Size { get; set; }
		
        /// <summary>
        /// These two bits define the height of the creature. It is used to check if missiles can fly over 
        /// the creatures (for example Fireballs can fly over small creatures).
        /// This value is also used to define how to animate a door that is closed upon the creature:
        /// '0': the door is not animated and stays fully open. The creature still takes damage.
        /// '1': the door is animated from the top to 1/4th of its size. This applies to tall creatures like Mummies.
        /// '2': the door is animated between 1/4th of its size to half of its size. This applies to medium sized creatures like Screamers.
        /// '3': the door is animated from half of its size to 3/4th of its size. This applies to small creatures like the Worm.
        /// 
        /// Note: This value is ignored for non material creatures and the door always closes normally without causing any damage to such creatures.
        /// </summary>
        [XmlAttribute]
        public int Height { get; set; }		

        /// <summary>
        /// The base value for computing how much damage a creature's attack will inflict.
        /// </summary>
        [XmlAttribute]
        public int AttackPower { get; set; }

        /// <summary>
        /// This value is used as a multiplier to compute the experience earned by champions when killing the creature.
        /// </summary>
        [XmlAttribute]
        public int ExperienceClass { get; set; }

        [XmlAttribute]
        public DamageType DamageType { get; set; }

        public SKILL[] Skills { get; set; }

        [XmlAttribute]
        public CHARFLAGS CharFlags { get; set; }

        /// <summary>
        /// If monster, how many times u can cast spell.
        /// </summary>
        [XmlAttribute]
        public int SpellCharges { get; set; }
		
        /// <summary>
        /// Movement speed timer.
        /// </summary>
		[XmlAttribute]
		public int MovementSpeed { get; set; }
		
		// Info from http://dungeon-master.com/forum/viewtopic.php?f=46&t=26563, All monster characteristics
		// Not all of these we can use !!! For some values we have different mechanics...
		////////////////////////////////////////////////////////////////////////////////////////////////////
		
		/// <summary>
		/// The defense value of the monster.
		/// </summary>
		[XmlAttribute]
		public int Armor {get;set;}
		
		/// <summary>
		///  The base health value of a monster. This value will be the base value used when calculating how much health a monster has when created via a monster generator actuator.
		/// </summary>
		[XmlAttribute]
		public int BaseHealth {get;set;}
		
		/// <summary>
		///  The base value for calculating whether or not a monster's attack hits or misses.
		/// </summary>
		[XmlAttribute]
		public int HitProbability {get;set;}
		
		/// <summary>
		/// This value dictates what kind of attack the monster uses. Here is a compiled list of what each value represents, but is not 100% perfect nor tested:
		/// </summary>
		/// public int AttackType {get;set;}
		
		/// <summary>
		/// The minimum amount of time required to pass before a monster can move again.
		/// </summary>
		[XmlAttribute]
		public int MoveSpeed {get;set;}
		
		/// <summary>
		/// The minimum amount of time required to pass before a monster can attack again.		
		/// </summary>
		[XmlAttribute]
		public int AttackSpeed {get;set;}
		
		/// <summary>
		/// The amount of poison inflicted when the monster successfully hits a character.	
		/// </summary>
		[XmlAttribute]
		public int Poison {get;set;}
		
		/// <summary>
		/// How far the monster can see, used in AI calculations.
        /// Reaction range of monster in squares.
        /// Maximum number of tiles between creature and party needed to see the party. 
        /// This applies only if the creature is facing the party. 
        /// This value is affected by the current light level in the dungeon (the value is halved for each level of darkness).
		/// </summary>
		[XmlAttribute]
		public int SightRange {get;set;}
		
		/// <summary>
		/// How far the monster can automatically detect the player and persue them. Monster is tying to approach to creature - if that creature is hostile...
		/// </summary>
		[XmlAttribute]
		public int Awareness {get;set;}
		
		/// <summary>
		/// How far the monster can be to attack from a distance
		/// </summary>
		[XmlAttribute]
		public int CastingSpellRange {get;set;}		
		
        /// <summary>
        /// Resistance to War Cry, Calm, Brandish and Blow Horn (maybe also Confuse). 
        /// With a value of 15, the creature is never afraid.
        /// </summary>
        [XmlAttribute]
        public int Bravery { get; set; }	

        /// <summary>
        /// The creature will tend to stay in the back row while other creatures will step up to the front row when the party is near and they want to attack.
        /// </summary>
        [XmlAttribute]
        public bool PreferBackRow { get; set; }		
		
        /// <summary>
        /// If this bit is set to '1', the creature can attack any champion in the party, even the ones in the back.
        /// If both 'Prefer back row' and 'Attack any champion' flags are set to '0', the creature will move to the front
        /// row of its tile. In other cases the creature has a 25% chance of moving to the front row.
        /// </summary>
        [XmlAttribute]
        public bool AttackAnyChampion { get; set; }		
		
        public CreatureInfo()
        {
            Inventory = new Inventory();
            Attributes = new Attributes();
            Resistances = new Resistances();
			Abilities = new CreatureAbilites();
			Flags = new CreatureFlags();
			AIFlags = new CreatureAIFlags();
            Ouches = new CreatureOuches();
			
            Skills = new SKILL[20];
        }

        public CreatureData CreateData()
        {
            CreatureData cd = new CreatureData();

            cd.ShortName = ShortName;
            cd.LongName = LongName;
			
            cd.InfoId = Id;
            cd.GfxId = GfxId;
            cd.Id = cd.InfoId + "_" + Guid.NewGuid();
			
            cd.Attributes = (Attributes)Attributes.Clone();
            cd.Inventory = (Inventory)Inventory.Clone();
			
            cd.Flags = (CreatureFlags)Flags.Clone();
			cd.AIFlags = (CreatureAIFlags)AIFlags.Clone();
			cd.CreatureType = CreatureType;				// NPC, Monster or Player?

            cd.Ouches = (CreatureOuches)Ouches.Clone();

            cd.Resistances = (Resistances)Resistances.Clone();
            cd.Skills = new List<SKILL>(Skills).ToArray();
            cd.CharFlags = CharFlags;
            cd.SpellCharges = SpellCharges;
            cd.Facing = Directions.North;
			cd.MovementSpeed = MovementSpeed;

            Root.I.CreatureSystem.AddData(cd);

            Root.log.InfoFormat("Core, Created new object with id: {0} based on object {1}", cd.Id, cd.InfoId);
            return cd;
        }
    }
	
	public enum CreatureType
	{
		None = 0,
		NPC = 10,
		Monster = 20,
		Player = 100
	}
}
